package com.carleasoft.mps.cms.business.train.service.Impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carleasoft.mps.cms.business.article.constants.ExceptionCMSEnum;
import com.carleasoft.mps.cms.business.drug.bean.entity.DrugOilManage;
import com.carleasoft.mps.cms.business.drug.service.DrugOilManageService;
import com.carleasoft.mps.cms.business.process.bean.po.MyApprovalPageCarPo;
import com.carleasoft.mps.cms.business.process.bean.po.NodePo;
import com.carleasoft.mps.cms.business.process.service.BaseProcessNodeRelService;
import com.carleasoft.mps.cms.business.train.bean.entity.TrainCar;
import com.carleasoft.mps.cms.business.train.bean.entity.TrainConsume;
import com.carleasoft.mps.cms.business.train.bean.entity.TrainConsumeItem;
import com.carleasoft.mps.cms.business.train.bean.entity.TrainDuty;
import com.carleasoft.mps.cms.business.train.bean.po.*;
import com.carleasoft.mps.cms.business.train.bean.vo.*;
import com.carleasoft.mps.cms.business.train.constants.ExceptionTrainEnum;
import com.carleasoft.mps.cms.business.train.dao.TrainCarMapper;
import com.carleasoft.mps.cms.business.train.dao.TrainExamMapper;
import com.carleasoft.mps.cms.business.train.dao.TrainPlanMapper;
import com.carleasoft.mps.cms.business.train.service.*;
import com.carleasoft.mps.cms.utils.ObjectSelfUtil;
import com.carleasoft.mps.core.exceptions.BusinessException;
import com.carleasoft.mps.core.user.ThreadUserContext;
import com.carleasoft.mps.core.user.UserCacheData;
import com.carleasoft.mps.core.utils.DateUtil;
import com.carleasoft.mps.core.utils.IBeanUtil;
import com.carleasoft.mps.excel.utils.ConvertTemplatePath;
import com.carleasoft.mps.excel.utils.ExcelUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 训练用车 服务实现类
 * </p>
 *
 * @author fan
 * @since 2023-05-17
 */
@Service
public class TrainCarServiceImpl extends ServiceImpl<TrainCarMapper, TrainCar> implements TrainCarService {

    @Autowired
    private TrainConsumeService trainConsumeService;
    @Autowired
    private TrainDutyService trainDutyService;
    @Autowired
    private TrainConsumeItemService trainConsumeItemService;
    @Autowired
    private TrainPlanMapper trainPlanMapper;
    @Autowired
    private TrainExamMapper trainExamMapper;
    @Autowired
    private TrainScoreService trainScoreService;
    @Autowired
    private BaseProcessNodeRelService baseProcessNodeRelService;
    @Autowired
    private DrugOilManageService drugOilManageService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String add(TrainCarAddOrEditPo trainCarAddOrEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        TrainCar trainCar = new TrainCar();
        BeanUtils.copyProperties(trainCarAddOrEditPo, trainCar);
        String code = UUID.randomUUID().toString().replaceAll("-", "");
        trainCar.setCarCode(code);
        if (Objects.nonNull(user) && user.getUserCode() != null) {
            trainCar.setCreatePersonCode(user.getUserCode());
            trainCar.setCreatePersonName(user.getUserName());
            trainCar.setUpdatePersonCode(user.getUserCode());
            trainCar.setUpdatePersonName(user.getUserName());
        }

        trainCar.setCreateTime(LocalDateTime.now());

        trainCar.setUpdateTime(LocalDateTime.now());
        if (trainCarAddOrEditPo.getResourceStatus() != null && trainCarAddOrEditPo.getResourceStatus() == 3) {
            trainCar.setStatus(3);//审批拒绝
        } else if (trainCarAddOrEditPo.getResourceStatus() != null && trainCarAddOrEditPo.getResourceStatus() == 2) {
            trainCar.setStatus(2);//审批通过
        }else {
            trainCar.setStatus(1);//待审批
        }

        this.save(trainCar);
        return code;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean edit(TrainCarAddOrEditPo trainCarAddOrEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        IBeanUtil.paramVerify(trainCarAddOrEditPo, "carCode");
        LambdaQueryWrapper<TrainCar> eq = Wrappers.lambdaQuery(TrainCar.class).eq(TrainCar::getCarCode, trainCarAddOrEditPo.getCarCode());
        TrainCar trainCar = new TrainCar();
        BeanUtils.copyProperties(trainCarAddOrEditPo, trainCar);
        trainCar.setUpdatePersonCode(user.getUserCode());
        trainCar.setUpdatePersonName(user.getUserName());
        trainCar.setUpdateTime(LocalDateTime.now());
        return this.update(trainCar, eq);
    }

    @Override
    public boolean editStatus(TrainCarAddOrEditPo trainCarAddOrEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        IBeanUtil.paramVerify(trainCarAddOrEditPo, "carCode");
        UpdateWrapper<TrainCar> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("STATUS", trainCarAddOrEditPo.getStatus());
        updateWrapper.set("UPDATE_PERSON_CODE", user.getUserCode());
        updateWrapper.set("UPDATE_PERSON_NAME", user.getUserName());
        updateWrapper.set("UPDATE_TIME", LocalDateTime.now());
        updateWrapper.eq("CAR_CODE", trainCarAddOrEditPo.getCarCode());
        return this.update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(TrainCar trainCar) {
        IBeanUtil.paramVerify(trainCar, "carCode");
        LambdaQueryWrapper<TrainCar> eq = Wrappers.lambdaQuery(TrainCar.class).eq(TrainCar::getCarCode, trainCar.getCarCode());
        return this.remove(eq);
    }

    @Override
    public Page<TrainCarVo> pageQuery(TrainCarPageQueryPo trainCarPageQueryPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        trainCarPageQueryPo.setLoginCode(user.getUserCode());
        Page page = new Page(trainCarPageQueryPo.getCurrent(), trainCarPageQueryPo.getSize());
        Page<TrainCarVo> trainCarVoPage = this.baseMapper.pageQuery(page, trainCarPageQueryPo);
        return trainCarVoPage;
    }

    @Override
    public TrainCarDetailVo detail(TrainCar trainCar) {
        IBeanUtil.paramVerify(trainCar, "carCode");
        TrainCarDetailVo trainCarDetailVo = this.baseMapper.detail(trainCar.getCarCode());
//        LambdaQueryWrapper<TrainCar> eq = Wrappers.lambdaQuery(TrainCar.class).eq(TrainCar::getCarCode, trainCar.getCarCode());
//        TrainCar one = this.getOne(eq);
//        BeanUtils.copyProperties(one,trainCarDetailVo);
        return trainCarDetailVo;
    }

    @Override
    public boolean trainCarImport(List<TrainCar> trainCarList) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        trainCarList.stream().forEach(a -> {
            a.setCarCode(UUID.randomUUID().toString().replaceAll("-", ""));
            a.setCreatePersonCode(user.getUserCode());
            a.setCreatePersonName(user.getUserName());
            a.setCreateTime(LocalDateTime.now());
            a.setUpdatePersonCode(user.getUserCode());
            a.setUpdatePersonName(user.getUserName());
            a.setUpdateTime(LocalDateTime.now());
        });
        return this.saveBatch(trainCarList);
    }

    @Override
    public boolean trainCarDownload(HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        String path = "\\templates\\trainCarTemplate.xls";
        TemplateExportParams templatePath = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path));
        try {
            ExcelUtils.exportExcel(templatePath, map, "用车模板下载", response);
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.TEMP_ERROR);
        }
        return true;
    }

    @Override
    public boolean importCar(MyApprovalPageCarPo myApprovalPageCarPo, HttpServletResponse response) {
        List<ImportCarVo> importCarVos = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        myApprovalPageCarPo.setCurrent(1);
        myApprovalPageCarPo.setSize(10000L);
        Page<TrainCarVo> trainCarVoPage = baseProcessNodeRelService.myApprovalPageCar(new Page(myApprovalPageCarPo.getCurrent(), myApprovalPageCarPo.getSize()), myApprovalPageCarPo);
        List<TrainCarVo> records = new ArrayList<>();
        records = trainCarVoPage.getRecords();
        if (StrUtil.isNotBlank(myApprovalPageCarPo.getStartTime()) && StrUtil.isNotBlank(myApprovalPageCarPo.getEndTime())) {
            myApprovalPageCarPo.setStartTime(myApprovalPageCarPo.getStartTime() + " 00:00:00");
            myApprovalPageCarPo.setEndTime(myApprovalPageCarPo.getEndTime() + " 23:59:59");
            for (TrainCarVo record : records) {
                String arriveDate = record.getArriveDate();
                List<LocalDateTime> list = JSON.parseArray(arriveDate, LocalDateTime.class);
                record.setTime(list.get(0));
            }
            LocalDateTime parse = LocalDateTime.parse(myApprovalPageCarPo.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDateTime dateTime = LocalDateTime.parse(myApprovalPageCarPo.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            records = records.stream().filter(s -> s.getTime() != null && s.getTime().isAfter(parse) && s.getTime().isBefore(dateTime)).collect(Collectors.toList());
        }
        for (TrainCarVo record : records) {
            ImportCarVo importCarVo = new ImportCarVo();
            importCarVo.setPart(record.getPartName());
            importCarVo.setCadre(record.getCadre());
            Integer carType = record.getCarType();
            String carTypeName = null;
            switch (carType) {
                case 1:
                    carTypeName = "长途用车";
                    break;
                case 2:
                    carTypeName = "预约长途车";
                    break;
                case 3:
                    carTypeName = "战备训练用车";
                    break;
                case 4:
                    carTypeName = "检查督查";
                    break;
                case 5:
                    carTypeName = "生活保障";
                    break;
                case 6:
                    carTypeName = "日常办公";
                    break;
                case 7:
                    carTypeName = "营区内动车";
                    break;
            }
            importCarVo.setCarType(carTypeName);
            importCarVo.setDriveName(record.getDriveName());
            importCarVo.setDriveLength(record.getDriveLength());
            importCarVo.setCarCard(record.getCarCard());
            importCarVo.setCarNumber(record.getCarNumber());
            importCarVo.setCarModel(record.getCarModel());
            importCarVo.setCarAddress(record.getCarAddress());
            importCarVo.setCarLength(record.getCarLength());
            String arriveDate = record.getArriveDate();
            List<String> list = JSON.parseArray(arriveDate, String.class);
            importCarVo.setArriveDateStart(list.get(0));
            importCarVo.setArriveDateEnd(list.get(1));
            importCarVo.setRemark(record.getRemark());
            importCarVos.add(importCarVo);
        }
        map.put("purchaseList", importCarVos);
        String path = "\\templates\\carTemplate.xlsx";
        TemplateExportParams templatePath = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path));
        try {
            ExcelUtils.exportExcel(templatePath, map, "报车用车", response);
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.TEMP_ERROR);
        }
        return true;
    }

    @Override
    public Workbook importCarCount(HttpServletResponse response, String startTime) throws ParseException {
        List<TrainCar> trainCars = new ArrayList<>();
        Date currentDate = null;
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
        Date date = ft.parse(startTime);
        if (startTime!=null) {
            currentDate = date;
            trainCars = this.list(Wrappers.<TrainCar>lambdaQuery()
                    .ne(TrainCar::getStatus, 3)
                    .like(TrainCar::getCreateTime, startTime));
        } else {
            currentDate = new Date();
            trainCars = this.list(Wrappers.<TrainCar>lambdaQuery()
                    .ne(TrainCar::getStatus, 3)
                    .like(TrainCar::getCreateTime, new Date()));
        }
        if (CollUtil.isEmpty(trainCars)) {
            throw new BusinessException("1008611", "没有数据不允许导出");
        }
        Map<Integer, List<TrainCar>> map = trainCars.stream().collect(Collectors.groupingBy(TrainCar::getCarType));
        // 长途用车
        List<TrainCar> ones = new ArrayList<>();
        // 预报长途用车
        List<TrainCar> twos = new ArrayList<>();
        // 战备训练
        List<TrainCar> threes = new ArrayList<>();
        // 检查督查
        List<TrainCar> fours = new ArrayList<>();
        // 生活保障
        List<TrainCar> fives = new ArrayList<>();
        // 日常办公
        List<TrainCar> sexs = new ArrayList<>();
        //  营区内动车
        List<TrainCar> sevens = new ArrayList<>();
        if (map.containsKey(1)) {
            ones = map.get(1);
            for (int i = 1; i < ones.size() + 1; i++) {
                TrainCar trainCar = ones.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(2)) {
            twos = map.get(2);
            for (int i = 1; i < twos.size() + 1; i++) {
                TrainCar trainCar = twos.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(3)) {
            threes = map.get(3);
            for (int i = 1; i < threes.size() + 1; i++) {
                TrainCar trainCar = threes.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(4)) {
            fours = map.get(4);
            for (int i = 1; i < fours.size() + 1; i++) {
                TrainCar trainCar = fours.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(5)) {
            fives = map.get(5);
            for (int i = 1; i < fives.size() + 1; i++) {
                TrainCar trainCar = fives.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(6)) {
            sexs = map.get(6);
            for (int i = 1; i < sexs.size() + 1; i++) {
                TrainCar trainCar = sexs.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        if (map.containsKey(7)) {
            sevens = map.get(7);
            for (int i = 1; i < sevens.size() + 1; i++) {
                TrainCar trainCar = sevens.get(i - 1);
                trainCar.setIndex(i);
            }
        }
        // 存放数据map
        Map<String, Object> carMap = new HashMap<String, Object>();
        carMap.put("listOne", ones);
        carMap.put("listTwo", twos);
        carMap.put("listThree", threes);
        carMap.put("listFour", fours);
        carMap.put("listFive", fives);
        carMap.put("listSex", sexs);
        carMap.put("listSeven", sevens);
//        String month = DateUtil.getMonth();
//        String day = DateUtil.getDay();
        String month = DateUtil.getTimeStr(currentDate, "MM");
        String day = DateUtil.getTimeStr(currentDate, "dd");

        carMap.put("date", month + "月" + day + "日");
        int aaa = 0;
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        int e = 0;
        int f = 0;
        int g = 0;
        if (map.containsKey(1)) {
            a = map.get(1).size();
            carMap.put("typeOne", map.get(1).size());

        }
        if (map.containsKey(2)) {
            b = map.get(2).size();
            carMap.put("typeOne", map.get(2).size());

        }
        if (map.containsKey(3)) {
            c = map.get(3).size();
            carMap.put("typeTwo", map.get(3).size());

        }
        if (map.containsKey(4)) {
            d = map.get(4).size();
            carMap.put("typeThree", map.get(4).size());

        }
        if (map.containsKey(5)) {
            e = map.get(5).size();
            carMap.put("typeFour", map.get(5).size());

        }
        if (map.containsKey(6)) {
            f = map.get(6).size();
            carMap.put("typeFive", map.get(6).size());

        }
        if (map.containsKey(7)) {
            g = map.get(7).size();
            carMap.put("typeSix", map.get(7).size());
        }
        aaa = a + c + d + e + f + g;
        carMap.put("typeSeven", aaa);
        // 设置导出配置
        // 获取导出excel指定模版,true开启多个sheet
        String path = "\\templates\\carCountImportOneOne.xls";
        TemplateExportParams params = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path), true);
        // 设置sheetName，若不设置该参数，则使用得原本得sheet名称

        String[] sheetNameArray = {"旅表(" + aaa + ")", "长途(" + a + ")", "预报长途(" + b + ")", "战备训练(" + c + ")", "检查督查(" + d + ")", "生活保障(" + e + ")", "日常办公(" + f + ")"
                , "营区内动车(" + g + ")"};
        params.setSheetName(sheetNameArray);
        // 导出excel
        return ExcelExportUtil.exportExcel(params, carMap);
    }

    @Override
    public List<TrainCar> trainCarParse(MultipartFile file) {
        List<TrainCar> trainCarList = new LinkedList<>();
        if (file.isEmpty()) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        List<TrainCarExcelMappingEntity> fl = new ArrayList<>();
        try {
            fl = ExcelUtils.importExcel(file, TrainCarExcelMappingEntity.class);
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
            fl = fl.stream().filter(purchaseListEntity -> !ObjectSelfUtil.isAllFieldNull(purchaseListEntity)).collect(Collectors.toList());
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
            if (!fl.isEmpty()) {
                fl.stream().forEach(a -> {
                    TrainCar trainCar = new TrainCar();
                    BeanUtils.copyProperties(a, trainCar);
                    trainCarList.add(trainCar);
                });
            }
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        return trainCarList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeAdd(ConsumeAddOrEditPo consumeAddOrEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        List<ConsumeUtilPo> consumeUtilPo = consumeAddOrEditPo.getConsumeUtilPo();
        List<TrainConsume> trainConsumeLinkedList = new LinkedList<>();
        consumeUtilPo.stream().forEach(a -> {
            TrainConsume trainConsume = new TrainConsume();
            BeanUtils.copyProperties(consumeAddOrEditPo, trainConsume);
            trainConsume.setConsumeCode(UUID.randomUUID().toString().replaceAll("-", ""));
            trainConsume.setCreatePersonCode(user.getUserCode());
            trainConsume.setCreatePersonName(user.getUserName());
            trainConsume.setCreateTime(LocalDateTime.now());
            trainConsume.setUpdatePersonCode(user.getUserCode());
            trainConsume.setUpdatePersonName(user.getUserName());
            trainConsume.setUpdateTime(LocalDateTime.now());
            trainConsume.setPart(a.getTargetItem());
            trainConsume.setExexutor(a.getExecutor());
            trainConsume.setStatus(1);
            trainConsumeLinkedList.add(trainConsume);
        });
        trainConsumeService.saveBatch(trainConsumeLinkedList);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeEdit(ConsumeAddOrEditPo consumeAddOrEditPo) {
        IBeanUtil.paramVerify(consumeAddOrEditPo, "consumeCode");
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        TrainConsume trainConsume = new TrainConsume();
        BeanUtils.copyProperties(consumeAddOrEditPo, trainConsume);
        trainConsume.setUpdatePersonCode(user.getUserCode());
        trainConsume.setUpdatePersonName(user.getUserName());
        trainConsume.setUpdateTime(LocalDateTime.now());
        LambdaQueryWrapper<TrainConsume> eq = Wrappers.lambdaQuery(TrainConsume.class).eq(TrainConsume::getConsumeCode, consumeAddOrEditPo.getConsumeCode());
        return trainConsumeService.update(trainConsume, eq);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeDelete(TrainConsume trainConsume) {
        IBeanUtil.paramVerify(trainConsume, "consumeCode");
        LambdaQueryWrapper<TrainConsume> eq = Wrappers.lambdaQuery(TrainConsume.class).eq(TrainConsume::getConsumeCode, trainConsume.getConsumeCode());
        return trainConsumeService.remove(eq);
    }

    @Override
    public Page<TrainConsumeVo> consumePageQuery(TrainConsumePageQueryPo trainConsumePageQueryPo) {
        Page page = new Page(trainConsumePageQueryPo.getCurrent(), trainConsumePageQueryPo.getSize());
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        trainConsumePageQueryPo.setUserCode(user.getUserCode());
        Page<TrainConsumeVo> trainConsumeVoPage = trainConsumeService.consumePageQuery(page, trainConsumePageQueryPo);
        List<UserVo> personMap = trainPlanMapper.getPersonMap();
        Map<String, String> map = personMap.stream().collect(Collectors.toMap(UserVo::getUserCode, UserVo::getUserName, (k1, k2) -> k1));
        List<TrainConsumeVo> records = trainConsumeVoPage.getRecords();
        List<DeptVo> dept = trainPlanMapper.getDept();
        Map<String, String> deptMap = dept.stream().collect(Collectors.toMap(DeptVo::getDeptCode, DeptVo::getDeptName, (k1, k2) -> k1));
        //处理执行人和处理目标对象
        if (!records.isEmpty()) {
            records.stream().forEach(a -> {
                String name = "";
                String code = "";
                JSONArray jsonArray = JSONObject.parseArray(a.getExexutor());
                if (jsonArray != null && !jsonArray.isEmpty()) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        String s = map.get(jsonArray.get(i));
                        name += s;
                        code += jsonArray.get(i);
                        if (i < jsonArray.size() - 1) {
                            name += ",";
                            code += ",";
                        }
                    }
                }
                a.setExexutor(name);
                a.setExexutorCode(code);
                //  处理目标对象
                String deptName = "";
                String deptCode = "";
                JSONArray deptArray = JSONObject.parseArray(a.getPart());
                if (deptArray != null && !deptArray.isEmpty()) {
                    for (int i = 0; i < deptArray.size(); i++) {
                        String s = deptMap.get(deptArray.get(i));
                        deptName += s;
                        deptCode += deptArray.get(i);
                        if (i < deptArray.size() - 1) {
                            deptName += ",";
                            deptCode += ",";
                        }
                    }
                }
                a.setPart(deptName);
                a.setPartCode(deptCode);
            });
        }

        return trainConsumeVoPage;
    }

    @Override
    public TrainConsumeDetailVo consumeDetail(TrainConsume trainConsume) {
        IBeanUtil.paramVerify(trainConsume, "consumeCode");
        LambdaQueryWrapper<TrainConsume> eq = Wrappers.lambdaQuery(TrainConsume.class).eq(TrainConsume::getConsumeCode, trainConsume.getConsumeCode());
        TrainConsumeDetailVo trainConsumeDetailVo = new TrainConsumeDetailVo();
        TrainConsume one = trainConsumeService.getOne(eq);
        List<UserVo> personMap = trainPlanMapper.getPersonMap();
        Map<String, String> map = personMap.stream().collect(Collectors.toMap(UserVo::getUserCode, UserVo::getUserName, (k1, k2) -> k1));
        List<DeptVo> dept = trainPlanMapper.getDept();
        Map<String, String> deptMap = dept.stream().collect(Collectors.toMap(DeptVo::getDeptCode, DeptVo::getDeptName, (k1, k2) -> k1));
        if (one != null) {
            BeanUtils.copyProperties(one, trainConsumeDetailVo);
            String name = "";
            String code = "";
            JSONArray jsonArray = JSONObject.parseArray(trainConsumeDetailVo.getExexutor());
            if (jsonArray != null && !jsonArray.isEmpty()) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    String s = map.get(jsonArray.get(i));
                    name += s;
                    code += jsonArray.get(i);
                    if (i < jsonArray.size() - 1) {
                        name += ",";
                        code += ",";
                    }
                }
            }
            trainConsumeDetailVo.setExexutor(name);
            trainConsumeDetailVo.setExexutorCode(code);
            //  处理目标对象
            String deptName = "";
            String deptCode = "";
            JSONArray deptArray = JSONObject.parseArray(trainConsumeDetailVo.getPart());
            if (deptArray != null && !deptArray.isEmpty()) {
                for (int i = 0; i < deptArray.size(); i++) {
                    String s = deptMap.get(deptArray.get(i));
                    deptName += s;
                    deptCode += deptArray.get(i);
                    if (i < deptArray.size() - 1) {
                        deptName += ",";
                        deptCode += ",";
                    }
                }
            }
            trainConsumeDetailVo.setPart(deptName);
            trainConsumeDetailVo.setPartCode(deptCode);
        }

        return trainConsumeDetailVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeMaintainAdd(TrainConsumeItemAddOrEdit trainConsumeItemAddOrEdit) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        int count = trainConsumeItemService.count(new QueryWrapper<TrainConsumeItem>().eq("ITEM_NAME", trainConsumeItemAddOrEdit.getItemName()).eq("CONSUME_CODE", trainConsumeItemAddOrEdit.getConsumeCode()));
        if (count > 0) {
            throw new BusinessException(ExceptionTrainEnum.DRUG_ERROR);
        }
        TrainConsumeItem trainConsumeItem = new TrainConsumeItem();
        BeanUtils.copyProperties(trainConsumeItemAddOrEdit, trainConsumeItem);
        trainConsumeItem.setItemCode(UUID.randomUUID().toString().replaceAll("-", ""));
        trainConsumeItem.setCreatePersonCode(user.getUserCode());
        trainConsumeItem.setCreatePersonName(user.getUserName());
        trainConsumeItem.setCrteaTime(LocalDateTime.now());
        trainConsumeItem.setUpdatePersonCode(user.getUserCode());
        trainConsumeItem.setUpdatePersonName(user.getUserName());
        trainConsumeItem.setUpdateTime(LocalDateTime.now());
        return trainConsumeItemService.save(trainConsumeItem);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeMaintainEdit(TrainConsumeItemAddOrEdit trainConsumeItemAddOrEdit) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        IBeanUtil.paramVerify(trainConsumeItemAddOrEdit, "itemCode");
        TrainConsumeItem trainConsumeItem = new TrainConsumeItem();
        LambdaQueryWrapper<TrainConsumeItem> eq = Wrappers.lambdaQuery(TrainConsumeItem.class).eq(TrainConsumeItem::getItemCode, trainConsumeItemAddOrEdit.getItemCode());
        UpdateWrapper<TrainConsume> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("UPDATE_PERSON_CODE", user.getUserCode());
        updateWrapper.set("UPDATE_PERSON_NAME", user.getUserName());
        updateWrapper.set("UPDATE_TIME", LocalDateTime.now());
        updateWrapper.eq("CONSUME_CODE", trainConsumeItemAddOrEdit.getConsumeCode());
        trainConsumeService.update(updateWrapper);
        return trainConsumeItemService.update(trainConsumeItem, eq);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeMaintainBatchEdit(TrainConsumeItemBatchEditPo trainConsumeItemBatchEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        List<TrainConsumeItem> trainConsumeItemList = trainConsumeItemBatchEditPo.getTrainConsumeItemList();
        Set<String> list = new HashSet<>();
        List<String> itemCodes = new LinkedList<>();
        trainConsumeItemList.stream().forEach(a -> {
            a.setUpdateTime(LocalDateTime.now());
            a.setUpdatePersonCode(user.getUserCode());
            a.setUpdatePersonName(user.getUserName());
            list.add(a.getConsumeCode());
            itemCodes.add(a.getItemCode());
        });
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM");
        String date = simpleDateFormat.format(new Date());
        trainConsumeItemService.consumeMaintainBatchEdit(trainConsumeItemList);
        boolean b = this.verifyMaintain(date, itemCodes);//校验是否维护完成
        UpdateWrapper<TrainConsume> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("UPDATE_PERSON_CODE", user.getUserCode());
        updateWrapper.set("UPDATE_PERSON_NAME", user.getUserName());
        updateWrapper.set("UPDATE_TIME", LocalDateTime.now());
        if (b) {
            updateWrapper.set("STATUS", 2);
        }
        if (!b) {
            updateWrapper.set("STATUS", 1);
        }
        updateWrapper.in("CONSUME_CODE", list);
        trainConsumeService.update(updateWrapper);
        return true;
    }

    /**
     * 校验消耗是否维护完成
     *
     * @param month
     * @param codes
     * @return boolean ture 维护完成 false 没有维护完成
     */
    boolean verifyMaintain(String month, List<String> codes) {
        QueryWrapper<TrainConsumeItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("ITEM_CODE", codes);
        queryWrapper.and(x -> {
            if (month.equals("01")) {
                x.isNull("JANUARY").or().eq("JANUARY", "");
            }
            if (month.equals("02")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
            }
            if (month.equals("03")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
            }
            if (month.equals("04")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
            }
            if (month.equals("05")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
            }
            if (month.equals("06")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
            }
            if (month.equals("07")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
            }
            if (month.equals("08")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
                x.or(a -> {
                    a.isNull("AUGUST").or().eq("AUGUST", "");
                });
            }
            if (month.equals("09")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
                x.or(a -> {
                    a.isNull("AUGUST").or().eq("AUGUST", "");
                });
                x.or(a -> {
                    a.isNull("SEPTEMABER").or().eq("SEPTEMABER", "");
                });
            }
            if (month.equals("10")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
                x.or(a -> {
                    a.isNull("AUGUST").or().eq("AUGUST", "");
                });
                x.or(a -> {
                    a.isNull("SEPTEMABER").or().eq("SEPTEMABER", "");
                });
                x.or(a -> {
                    a.isNull("OCTOBER").or().eq("OCTOBER", "");
                });
            }
            if (month.equals("11")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
                x.or(a -> {
                    a.isNull("AUGUST").or().eq("AUGUST", "");
                });
                x.or(a -> {
                    a.isNull("SEPTEMABER").or().eq("SEPTEMABER", "");
                });
                x.or(a -> {
                    a.isNull("OCTOBER").or().eq("OCTOBER", "");
                });
                x.or(a -> {
                    a.isNull("NOVEMBER").or().eq("NOVEMBER", "");
                });
            }
            if (month.equals("12")) {
                x.or(a -> {
                    a.isNull("JANUARY").or().eq("JANUARY", "");
                });
                x.or(a -> {
                    a.isNull("FEBRUARY").or().eq("FEBRUARY", "");
                });
                x.or(a -> {
                    a.isNull("MARCH").or().eq("MARCH", "");
                });
                x.or(a -> {
                    a.isNull("APRIL").or().eq("APRIL", "");
                });
                x.or(a -> {
                    a.isNull("MAY").or().eq("MAY", "");
                });
                x.or(a -> {
                    a.isNull("JUNE").or().eq("JUNE", "");
                });
                x.or(a -> {
                    a.isNull("JULY").or().eq("JULY", "");
                });
                x.or(a -> {
                    a.isNull("AUGUST").or().eq("AUGUST", "");
                });
                x.or(a -> {
                    a.isNull("SEPTEMABER").or().eq("SEPTEMABER", "");
                });
                x.or(a -> {
                    a.isNull("OCTOBER").or().eq("OCTOBER", "");
                });
                x.or(a -> {
                    a.isNull("NOVEMBER").or().eq("NOVEMBER", "");
                });
                x.or(a -> {
                    a.isNull("DECEMBER").or().eq("DECEMBER", "");
                });
            }
        });

        int count = trainConsumeItemService.count(queryWrapper);
        if (count > 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumeMaintainDelete(TrainConsumeItem trainConsumeItem) {
        IBeanUtil.paramVerify(trainConsumeItem, "itemCode");
        LambdaQueryWrapper<TrainConsumeItem> eq = Wrappers.lambdaQuery(TrainConsumeItem.class).eq(TrainConsumeItem::getItemCode, trainConsumeItem.getItemCode());
        return trainConsumeItemService.remove(eq);
    }

    @Override
    public Page<TrainConsumeItemVo> consumeMaintainPageQuery(TrainConsumeItemPageQueryPo trainConsume) {
        Page page = new Page(trainConsume.getCurrent(), trainConsume.getSize());
        return trainConsumeItemService.consumeMaintainPageQuery(page, trainConsume);
    }

    @Override
    public List<TrainConsumeItemVo> consumeMaintainList(TrainConsumeItemPageQueryPo trainConsume) {
        List<TrainConsumeItem> list = trainConsumeItemService.list(new QueryWrapper<TrainConsumeItem>().eq("CONSUME_CODE", trainConsume.getConsumeCode()));
        List<TrainConsumeItemVo> returnList = new LinkedList<>();
        if (!list.isEmpty()) {
            list.stream().forEach(a -> {
                TrainConsumeItemVo trainConsumeItemVo = new TrainConsumeItemVo();
                BeanUtils.copyProperties(a, trainConsumeItemVo);
                returnList.add(trainConsumeItemVo);
            });
        }

        return returnList;
    }

    @Override
    public TrainConsumeItemDetailVo consumeMaintainDetail(TrainConsumeItem trainConsumeItem) {
        TrainConsumeItemDetailVo trainConsumeItemDetailVo = new TrainConsumeItemDetailVo();
        IBeanUtil.paramVerify(trainConsumeItem, "itemCode");
        LambdaQueryWrapper<TrainConsumeItem> eq = Wrappers.lambdaQuery(TrainConsumeItem.class).eq(TrainConsumeItem::getItemCode, trainConsumeItem.getItemCode());
        TrainConsumeItem one = trainConsumeItemService.getOne(eq);
        if (one != null) {
            BeanUtils.copyProperties(one, trainConsumeItemDetailVo);
        }
        return trainConsumeItemDetailVo;
    }

    @Override
    public boolean consumeMaintainImport(String examCode, MultipartFile file) {
        boolean isOK = false;
        TrainConsume trainConsumeServiceOne = trainConsumeService.getOne(Wrappers.<TrainConsume>lambdaQuery()
                .eq(TrainConsume::getConsumeCode, examCode));
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        List<TrainConsumeItem> trainConsumeItemList = this.consumeMaintainParse(file);
        Set<String> itemNames = trainConsumeItemList.stream().map(TrainConsumeItem::getItemName).collect(Collectors.toSet());
        Integer consumeType = trainConsumeServiceOne.getConsumeType();
        if (consumeType == 1) {
            consumeType = 2;
        } else {
            consumeType = 1;
        }
        List<DrugOilManage> drugOilManages = drugOilManageService.list(Wrappers.<DrugOilManage>lambdaQuery()
                .in(DrugOilManage::getName, itemNames)
                .eq(DrugOilManage::getType, consumeType));
        String aaa = null;
        if (drugOilManages.size() != trainConsumeItemList.size()) {
            if (CollUtil.isNotEmpty(drugOilManages)) {
                Set<String> oldNames = drugOilManages.stream().map(DrugOilManage::getName).collect(Collectors.toSet());
                itemNames.removeAll(oldNames);
            }
            if (trainConsumeServiceOne.getConsumeType() == 1) {
                aaa = "油料";
            } else {
                aaa = "药品";
            }
            throw new BusinessException("1008611", "导入的" + aaa + "数据库中不存在，请核对后重新导入,不存在的+" + aaa + "有" + itemNames);
        }
        Map<String, DrugOilManage> map = drugOilManages.stream().collect(Collectors.toMap(DrugOilManage::getName, Function.identity()));
        trainConsumeItemList.stream().forEach(a -> {
            //处理消耗
            a.setConsumeCode(examCode);
            if (map.containsKey(a.getItemName())) {
                a.setDrugCode(map.get(a.getItemName()).getCode());
            } else {
                throw new BusinessException("1008611", "数据库不存在");
            }
            a.setItemCode(IdWorker.getIdStr());
            a.setItemConsume(this.parseConsume(a).toString());
            a.setUpdateTime(LocalDateTime.now());
            a.setUpdatePersonName(user.getUserName());
            a.setUpdatePersonCode(user.getUserCode());
            //计算执行率
            if (StringUtils.isNotBlank(a.getItemConsume()) && StringUtils.isNotBlank(a.getItemIndex()) && Double.parseDouble(a.getItemIndex()) != 0) {
                NumberFormat format = NumberFormat.getPercentInstance();
                //小数最大保留2位
                format.setMaximumFractionDigits(2);
                String str = format.format((Double.parseDouble(a.getItemConsume()) / (1.00 * Double.parseDouble(a.getItemIndex()))));
                a.setRate(str);
            }
        });
        List<TrainConsumeItem> trainConsumeItems = trainConsumeItemService.list(Wrappers.<TrainConsumeItem>lambdaQuery()
                .eq(TrainConsumeItem::getConsumeCode, examCode));
        if (CollUtil.isNotEmpty(trainConsumeItems)) {
            List<String> itemCodes = trainConsumeItems.stream().map(TrainConsumeItem::getItemCode).collect(Collectors.toList());
            isOK = trainConsumeItemService.remove(Wrappers.<TrainConsumeItem>lambdaQuery()
                    .in(TrainConsumeItem::getItemCode, itemCodes));
        }
        isOK = trainConsumeItemService.saveBatch(trainConsumeItemList);


        return isOK;
    }

    private Double parseConsume(TrainConsumeItem trainConsumeItem) {
        double all = 0.00;
        try {
            if (StringUtils.isNotBlank(trainConsumeItem.getJanuary())) {
                all += Double.parseDouble(trainConsumeItem.getJanuary());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getFebruary())) {
                all += Double.parseDouble(trainConsumeItem.getFebruary());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getMarch())) {
                all += Double.parseDouble(trainConsumeItem.getMarch());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getApril())) {
                all += Double.parseDouble(trainConsumeItem.getApril());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getMay())) {
                all += Double.parseDouble(trainConsumeItem.getMay());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getJune())) {
                all += Double.parseDouble(trainConsumeItem.getJune());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getJuly())) {
                all += Double.parseDouble(trainConsumeItem.getJuly());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getAugust())) {
                all += Double.parseDouble(trainConsumeItem.getAugust());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getSeptemaber())) {
                all += Double.parseDouble(trainConsumeItem.getSeptemaber());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getOctober())) {
                all += Double.parseDouble(trainConsumeItem.getOctober());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getNovember())) {
                all += Double.parseDouble(trainConsumeItem.getNovember());
            }

            if (StringUtils.isNotBlank(trainConsumeItem.getDecember())) {
                all += Double.parseDouble(trainConsumeItem.getDecember());
            }
        } catch (Exception e) {
            throw new BusinessException(ExceptionTrainEnum.IMPORT_ERROR);
        }
        return all;
    }

    @Override
    public boolean consumeMaintainDownload(TrainConsume trainConsume, HttpServletResponse response) {
        IBeanUtil.paramVerify(trainConsume, "consumeCode");
        TrainConsumeItemPageQueryPo trainConsumeItemPageQueryPo = new TrainConsumeItemPageQueryPo();
        trainConsumeItemPageQueryPo.setConsumeCode(trainConsume.getConsumeCode());
        List<TrainConsumeItemVo> trainConsumeItemVos = this.consumeMaintainList(trainConsumeItemPageQueryPo);
        Map<String, Object> map = new HashMap<>();
        map.put("list", trainConsumeItemVos);
        String path = "\\templates\\TrainConsumeItemTemplate.xls";
        TemplateExportParams templatePath = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path));
        try {
            ExcelUtils.exportExcel(templatePath, map, "消耗维护模板", response);
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.TEMP_ERROR);
        }
        return true;
    }

    @Override
    public List<TrainConsumeItem> consumeMaintainParse(MultipartFile file) {
        List<TrainConsumeItem> returnList = new LinkedList<>();
        if (file.isEmpty()) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        List<TrainConsumeItemExcelMappingEntity> fl = new ArrayList<>();
        try {
            fl = ExcelUtils.importExcel(file, TrainConsumeItemExcelMappingEntity.class);
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
            fl = fl.stream().filter(purchaseListEntity -> !ObjectSelfUtil.isAllFieldNull(purchaseListEntity)).collect(Collectors.toList());
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        if (fl != null && fl.size() > 0) {
            fl.stream().forEach(a -> {
                TrainConsumeItem trainConsumeItem = new TrainConsumeItem();
                BeanUtils.copyProperties(a, trainConsumeItem);
                returnList.add(trainConsumeItem);
            });
        }
        return returnList;
    }

    @Override
    public boolean consumeMaintainFinish(TrainConsume trainConsume) {
        IBeanUtil.paramVerify(trainConsume, "consumeCode");
        LambdaUpdateWrapper<TrainConsume> eq = Wrappers.lambdaUpdate(TrainConsume.class).set(TrainConsume::getStatus, 2).eq(TrainConsume::getConsumeCode, trainConsume.getConsumeCode());
        return trainConsumeService.update(eq);
    }

    @Override
    public boolean downloadExcelFile(TrainConsume trainConsume, HttpServletResponse response) {
        IBeanUtil.paramVerify(trainConsume, "consumeCode");
        TrainConsumeItemPageQueryPo trainConsumeItemPageQueryPo = new TrainConsumeItemPageQueryPo();
        trainConsumeItemPageQueryPo.setConsumeCode(trainConsume.getConsumeCode());
        List<TrainConsumeItemVo> trainConsumeItemVos = this.consumeMaintainList(trainConsumeItemPageQueryPo);
        Map<String, Object> map = new HashMap<>();
        map.put("list", trainConsumeItemVos);
        String path = "\\templates\\TrainConsumeItemFileTemplate.xls";
        TemplateExportParams templatePath = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path));
        try {
            ExcelUtils.exportExcel(templatePath, map, "消耗维护信息", response);
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.TEMP_ERROR);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean trainDutyAdd(TrainDutyAddOrEditPo trainDutyAddOrEditPo) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        TrainDuty trainDuty = new TrainDuty();
        BeanUtils.copyProperties(trainDutyAddOrEditPo, trainDuty);
        trainDuty.setDutyCode(UUID.randomUUID().toString().replaceAll("-", ""));
        trainDuty.setCreatePersonCode(user.getUserCode());
        trainDuty.setCreatePersonName(user.getUserName());
        trainDuty.setCreateTime(LocalDateTime.now());
        trainDuty.setUpdatePersonCode(user.getUserCode());
        trainDuty.setUpdatePersonName(user.getUserName());
        trainDuty.setUpdateTime(LocalDateTime.now());
        return trainDutyService.save(trainDuty);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean trainDutyEdit(TrainDutyAddOrEditPo trainDutyAddOrEditPo) {
        IBeanUtil.paramVerify(trainDutyAddOrEditPo, "dutyCode");
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        TrainDuty trainDuty = new TrainDuty();
        BeanUtils.copyProperties(trainDutyAddOrEditPo, trainDuty);
        trainDuty.setUpdatePersonCode(user.getUserCode());
        trainDuty.setUpdatePersonName(user.getUserName());
        trainDuty.setUpdateTime(LocalDateTime.now());
        LambdaQueryWrapper<TrainDuty> eq = Wrappers.lambdaQuery(TrainDuty.class).eq(TrainDuty::getDutyCode, trainDutyAddOrEditPo.getDutyCode());
        return trainDutyService.update(trainDuty, eq);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean trainDutyDelete(TrainDuty trainDuty) {
        IBeanUtil.paramVerify(trainDuty, "dutyCode");
        LambdaQueryWrapper<TrainDuty> eq = Wrappers.lambdaQuery(TrainDuty.class).eq(TrainDuty::getDutyCode, trainDuty.getDutyCode());
        return trainDutyService.remove(eq);
    }

    @Override
    public Page<TrainDutyVo> trainDutyPageQuery(TrainDutyPageQueryPo trainDutyPageQueryPo) {
        Page page = new Page(trainDutyPageQueryPo.getCurrent(), trainDutyPageQueryPo.getSize());
        return trainDutyService.trainDutyPageQuery(page, trainDutyPageQueryPo);
    }

    @Override
    public TrainDutyDetailVo trainDutyDetail(TrainDuty trainDuty) {
        IBeanUtil.paramVerify(trainDuty, "dutyCode");
        LambdaQueryWrapper<TrainDuty> eq = Wrappers.lambdaQuery(TrainDuty.class).eq(TrainDuty::getDutyCode, trainDuty.getDutyCode());
        TrainDuty one = trainDutyService.getOne(eq);
        TrainDutyDetailVo trainDutyDetailVo = new TrainDutyDetailVo();
        BeanUtils.copyProperties(one, trainDutyDetailVo);
        return trainDutyDetailVo;
    }

    @Override
    public boolean trainDutyImport(MultipartFile file) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        List<TrainDuty> trainDutyList = this.trainDutyParse(file);
        trainDutyList.stream().forEach(a -> {
            a.setDutyCode(UUID.randomUUID().toString().replaceAll("-", ""));
            a.setCreateTime(LocalDateTime.now());
            a.setCreatePersonCode(user.getUserCode());
            a.setCreatePersonName(user.getUserName());
            a.setUpdateTime(LocalDateTime.now());
            a.setUpdatePersonCode(user.getUserCode());
            a.setUpdatePersonName(user.getUserName());
        });
        return trainDutyService.saveBatch(trainDutyList);
    }

    @Override
    public boolean trainDutyDownload(HttpServletResponse response) {
        Map<String, Object> map = new HashMap<>();
        String path = "\\templates\\TrainDutyTemplate.xls";
        TemplateExportParams templatePath = new TemplateExportParams(ConvertTemplatePath.convertTemplatePath(path));
        try {
            ExcelUtils.exportExcel(templatePath, map, "训练日常消耗执勤", response);
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.TEMP_ERROR);
        }
        return true;
    }

    @Override
    public List<TrainDuty> trainDutyParse(MultipartFile file) {
        List<TrainDuty> returnList = new LinkedList<>();
        if (file.isEmpty()) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        List<TrainDutyExcelMappingEntity> fl = new ArrayList<>();
        try {
            fl = ExcelUtils.importExcel(file, TrainDutyExcelMappingEntity.class);
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
            fl = fl.stream().filter(purchaseListEntity -> !ObjectSelfUtil.isAllFieldNull(purchaseListEntity)).collect(Collectors.toList());
            if (CollUtil.isEmpty(fl)) {
                throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
            }
        } catch (IOException e) {
            throw new BusinessException(ExceptionTrainEnum.PARSE_ERROR);
        }
        if (fl != null && fl.size() > 0) {
            fl.stream().forEach(a -> {
                TrainDuty trainDuty = new TrainDuty();
                BeanUtils.copyProperties(a, trainDuty);
                returnList.add(trainDuty);
            });
        }
        return returnList;
    }

    @Override
    public TrainCarStatisticsVo trainCarStatistics() {
        TrainCarStatisticsVo trainCarStatisticsVo = new TrainCarStatisticsVo();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        String theMonth = simpleDateFormat.format(new Date());
        trainCarStatisticsVo.setTheMonthUseCar(this.baseMapper.statisticsTrainCar(1, theMonth));
        trainCarStatisticsVo.setTheMonthForecast(this.baseMapper.statisticsTrainCar(2, theMonth));
        trainCarStatisticsVo.setAllUseCar(this.baseMapper.statisticsTrainCar(1, null));
        trainCarStatisticsVo.setAllForecast(this.baseMapper.statisticsTrainCar(2, null));
        return trainCarStatisticsVo;
    }

    @Override
    public HashMap<String, Object> useStatistics(UseStatisticsPo useStatisticsPo) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("carType", this.baseMapper.statisticsTrainCarTypeByYear(useStatisticsPo.getYear()));
        hashMap.put("driveType", this.baseMapper.statisticsTrainCarDriveTypeByYear(useStatisticsPo.getYear()));
        return hashMap;
    }

    @Override
    public HashMap<String, Object> carOfYearStatistics() {
        HashMap<String, Object> hashMap = new HashMap<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        String theYear = simpleDateFormat.format(new Date());

        List<HashMap<String, Object>> carTypeList = new LinkedList<>();
        HashMap<String, Object> map = new HashMap<>();
        map.put("carType", 1);
        map.put("statistics", this.baseMapper.useCarNumByYear(1, theYear));//常规
        carTypeList.add(map);
        HashMap<String, Object> map2 = new HashMap<>();
        map2.put("carType", 2);
        map2.put("statistics", this.baseMapper.useCarNumByYear(2, theYear));//预报长途
        carTypeList.add(map2);

        hashMap.put("carTypeStatistics", carTypeList);

        List<HashMap<String, Object>> list = this.baseMapper.selectDict(4);
        List<HashMap<String, Object>> driveTypeList = new LinkedList<>();
        list.stream().forEach(a -> {
            HashMap<String, Object> driveMap = new HashMap<>();
            driveMap.put("driveType", a.get("dictValue"));
            driveMap.put("statistics", this.baseMapper.useCarNumDriveTypeByYear(a.get("code").toString(), theYear));
            driveTypeList.add(driveMap);
        });
        hashMap.put("driveTypeStatistics", driveTypeList);
        return hashMap;
    }

    @Override
    public List<HashMap<String, Object>> statisticalAnalysisDept() {
        List<String> dept = trainExamMapper.getDept();
        HashSet<String> deptCodes = new HashSet<>();
        deptCodes.add("-1");
        if (dept != null && dept.size() > 0) {
            dept.stream().forEach(a -> {
                JSONArray jsonArray = JSONArray.parseArray(a);
                for (int i = 0; i < jsonArray.size(); i++) {
                    deptCodes.add(jsonArray.get(i).toString());
                }
            });
        }
        return trainExamMapper.getDeptMsgByCodes(deptCodes);
    }

    @Override
    public HashMap<String, Object> statisticalAnalysisConsumption(StatisticalAnalysisConsumptionPo statisticalAnalysisConsumptionPo) {
        HashMap<String, Object> returnMap = new HashMap<>();
        List<HashMap<String, Object>> list = this.baseMapper.statisticalAnalysisConsumption(statisticalAnalysisConsumptionPo, 1);//油料
        List<HashMap<String, Object>> list1 = this.baseMapper.statisticalAnalysisConsumption(statisticalAnalysisConsumptionPo, 2);//弹药
        if (list != null) {
            returnMap.put("oil", list);
        } else {
            returnMap.put("oil", new LinkedList());
        }
        if (list1 != null) {
            returnMap.put("drug", list1);
        } else {
            returnMap.put("drug", new LinkedList());
        }
        return returnMap;
    }

    @Override
    public List<CarExcelVo> contentImportExcel(MultipartFile file) {
        List<CarExcelVo> list = null;
        try {
            list = ExcelUtils.importExcel(file, CarExcelVo.class);
            list = list.stream().filter(i -> i.getPartName() != null).collect(Collectors.toList());
        } catch (IOException e) {
            e.printStackTrace();
        }

        Set<String> deptNames = list.stream().map(CarExcelVo::getPartName).collect(Collectors.toSet());
        for (CarExcelVo carExcelVo : list) {
            if (carExcelVo.getCarType()==null){
                throw new BusinessException("1008611","报车用车类型未选择，请重新填写");
            }
        }
        // 单位
        List<DeptInfoVos> deptInfoVos = trainExamMapper.deptInfo(deptNames);
        Map<String, DeptInfoVos> map = deptInfoVos.stream().collect(Collectors.toMap(DeptInfoVos::getDeptName, Function.identity()));
        // 车型
//        String type = null;
//        type = "车型";
//        List<DictVo> carModelVos = this.getBaseMapper().dictVos(type);
//        Map<String, DictVo> voMap = carModelVos.stream().collect(Collectors.toMap(DictVo::getName, Function.identity()));
//        // 类别
//        type = "报车用车类别";
//        List<DictVo> driveTypeVos = this.getBaseMapper().dictVos(type);
//        Map<String, DictVo> dictVoMap = driveTypeVos.stream().collect(Collectors.toMap(DictVo::getName, Function.identity()));
        for (CarExcelVo carExcelVo : list) {
            DeptInfoVos infoVos = map.get(carExcelVo.getPartName());
            TrainCarAddOrEditPo trainCarAddOrEditPo = BeanUtil.copyProperties(carExcelVo, TrainCarAddOrEditPo.class);

            trainCarAddOrEditPo.setCarType(carExcelVo.getCarType());
            trainCarAddOrEditPo.setPart(carExcelVo.getPartName());
//            trainCarAddOrEditPo.setCarModel(voMap.get(carExcelVo.getCarModelName()).getCode());
//            trainCarAddOrEditPo.setDriveType(dictVoMap.get(carExcelVo.getDriveType()).getCode());
            trainCarAddOrEditPo.setCarModel(carExcelVo.getCarModelName());
            trainCarAddOrEditPo.setDriveType(carExcelVo.getDriveType());
            String startTime = carExcelVo.getStartTime();
            String endTime = carExcelVo.getEndTime();
            List<String> item = new ArrayList<>();
            item.add(startTime);
            item.add(endTime);
            String arriveDate = JSON.toJSONString(item);
            trainCarAddOrEditPo.setArriveDate(arriveDate);
            trainCarAddOrEditPo.setResourceStatus(Integer.valueOf(carExcelVo.getStatus()));
            this.add(trainCarAddOrEditPo);
//            NodePo nodePo = new NodePo();
//            nodePo.setType(3);
//            NodePo moduleInfo = baseProcessNodeRelService.getModuleInfo(nodePo);
//            NodePo nodePo1 = new NodePo();
//            nodePo1.setBaseNodePos(moduleInfo.getBaseNodePos());
//            nodePo1.setBisCode(add);
//            nodePo1.setType(3);
//            baseProcessNodeRelService.submitApproval(nodePo1);
        }
        if (list.size()==0){
            throw new BusinessException("1008611","导入失败，请检查模板是否正确");
        }
        return list;
    }

    private static final DecimalFormat decimalFormat = new DecimalFormat("###################.###########");


    @Override
    public List<ConsumeListVo> consumeList(ConsumeListPo consumeListPo) {
        List<ConsumeListVo> consumeListVos = new ArrayList<>();
        if (StrUtil.isNotBlank(consumeListPo.getDeptName())) {
            String deptCode = this.getBaseMapper().deptInfo(consumeListPo.getDeptName());
            consumeListPo.setDeptCode(deptCode);
        }
        if (StrUtil.isNotBlank(consumeListPo.getCreateTimeStart()) && StrUtil.isNotBlank(consumeListPo.getCreateTimeEnd())) {
            consumeListPo.setCreateTimeStart(consumeListPo.getCreateTimeStart() + " 00:00:00");
            consumeListPo.setCreateTimeEnd(consumeListPo.getCreateTimeStart() + " 23:59:59");
        }
        List<TrainConsume> trainConsumes = trainConsumeService.consumeList(consumeListPo);
        if (CollUtil.isNotEmpty(trainConsumes)) {
            List<String> codes = trainConsumes.stream().map(TrainConsume::getConsumeCode).collect(Collectors.toList());
            List<TrainConsumeItem> list = trainConsumeItemService.list(Wrappers.<TrainConsumeItem>lambdaQuery()
                    .in(TrainConsumeItem::getConsumeCode, codes));
            if (CollUtil.isNotEmpty(list)) {
                Map<String, List<TrainConsumeItem>> map = list.stream().collect(Collectors.groupingBy(TrainConsumeItem::getItemName));
                List<DrugOilManage> drugOilManages = drugOilManageService.list(Wrappers.<DrugOilManage>lambdaQuery()
                        .eq(DrugOilManage::getType, 1));
                for (DrugOilManage drugOilManage : drugOilManages) {
                    if (map.containsKey(drugOilManage.getName())) {
                        ConsumeListVo consumeListVo = new ConsumeListVo();
                        consumeListVo.setName(drugOilManage.getName());
                        List<TrainConsumeItem> trainConsumeItems = map.get(drugOilManage.getName());
                        BigDecimal reduce = trainConsumeItems.stream().map(TrainConsumeItem::getItemConsume).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        consumeListVo.setSum(reduce);
                        BigDecimal ddd = trainConsumeItems.stream().map(TrainConsumeItem::getItemIndex).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        consumeListVo.setTarget(ddd);
                        BigDecimal multiply = reduce.divide(ddd, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                        String format = decimalFormat.format(multiply);
                        consumeListVo.setRatio(format + "%");
                        consumeListVos.add(consumeListVo);
                    }
                }

            }
        }

        return consumeListVos;
    }


    /**
     * 使用easypoi导出文件
     * 单sheet / 多sheet
     *
     * @param response
     * @return
     */
    @RequestMapping(value = "exportexceltest")
    @ResponseBody
    public String exportExcelTest(HttpServletResponse response) {
        // 获取workbook对象
        // 单sheet或多sheet 只需要更改此处即可
        Workbook workbook = exportMoreSheetByTemplate();
        // 判断数据
        if (workbook == null) {
            return "fail";
        }
        // 设置excel的文件名称
        String excelName = "测试excel";
        // 重置响应对象
        response.reset();
        // 当前日期，用于导出文件名称
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//        String dateStr = "["+excelName+"-"+sdf.format(new Date())+"]";
        // 指定下载的文件名--设置响应头
        response.setHeader("Content-Disposition", "attachment;filename=" + "文件名" + ".xls");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 写出数据输出流到页面
        try {
            OutputStream output = response.getOutputStream();
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
            workbook.write(bufferedOutPut);
            bufferedOutPut.flush();
            bufferedOutPut.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }

    /**
     * 模版多sheet导出示例
     *
     * @return
     */
    public Workbook exportMoreSheetByTemplate() {
        List<TrainCar> trainCars = this.list(Wrappers.<TrainCar>lambdaQuery()
                .eq(TrainCar::getStatus, 3));
        Map<Integer, List<TrainCar>> map = trainCars.stream().collect(Collectors.groupingBy(TrainCar::getCarType));
        // 长途用车
        List<TrainCar> ones = new ArrayList<>();
        // 预报长途用车
        List<TrainCar> twos = new ArrayList<>();
        // 战备训练
        List<TrainCar> threes = new ArrayList<>();
        // 检查督查
        List<TrainCar> fours = new ArrayList<>();
        // 生活保障
        List<TrainCar> fives = new ArrayList<>();
        // 日常办公
        List<TrainCar> sexs = new ArrayList<>();
        //  营区内动车
        List<TrainCar> sevens = new ArrayList<>();
        if (map.containsKey(1)) {
            ones = map.get(1);
        }
        if (map.containsKey(2)) {
            twos = map.get(2);
        }
        if (map.containsKey(3)) {
            threes = map.get(3);
        }
        if (map.containsKey(4)) {
            fours = map.get(4);
        }
        if (map.containsKey(5)) {
            fives = map.get(5);
        }
        if (map.containsKey(6)) {
            sexs = map.get(6);
        }
        if (map.containsKey(7)) {
            sevens = map.get(7);
        }
        // 存放数据map
        Map<String, Object> carMap = new HashMap<String, Object>();
        carMap.put("listOne", ones);
        carMap.put("listTwo", twos);
        carMap.put("listThree", threes);
        carMap.put("listFour", fours);
        carMap.put("listFive", fives);
        carMap.put("listSex", sexs);
        carMap.put("listSeven", sevens);
        LocalDate now = LocalDate.now();
        carMap.put("date", now.getMonth() + "月" + now.getDayOfMonth() + "日");
        carMap.put("typeOne", 1);
        carMap.put("typeTwo", 2);
        carMap.put("typeThree", 3);
        carMap.put("typeFour", 4);
        carMap.put("typeFive", 5);
        carMap.put("typeSix", 6);
        carMap.put("typeSeven", 7);
        // 设置导出配置
        // 获取导出excel指定模版,true开启多个sheet
        TemplateExportParams params = new TemplateExportParams("\\templates\\carTemplate.xlsx", true);
        // 设置sheetName，若不设置该参数，则使用得原本得sheet名称
        String[] sheetNameArray = {"旅表（" + 1 + ")", "学生信息"};
        params.setSheetName(sheetNameArray);
        // 导出excel
        return ExcelExportUtil.exportExcel(params, carMap);
    }
}
